package benchmark_lucene;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

import myutil.MyStemmer;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import common_var.Path;
import evaluate.CalcMap;
import evaluate.Lisa_Que_Rel;

public class SearchLucene {
	String indexpath = new String("");
	public MyStemmer ms = new MyStemmer();

	public SearchLucene(String indexpath, MyStemmer ms) {// create a new stemmer
		// TODO Auto-generated constructor stub
		this.ms = ms;
		this.indexpath = indexpath;
	}

	public SearchLucene(String indexpath) {
		// TODO Auto-generated constructor stub

		this.indexpath = indexpath;
	}

	public ArrayList<Integer> Search(String[] fields, String rawquery) {
		ArrayList<Integer> idlist = new ArrayList<Integer>();
		IndexReader ir = null;
		try {
			ir = DirectoryReader.open(FSDirectory.open(new File(indexpath)));
			IndexSearcher searcher = new IndexSearcher(ir);

			// --------------queries---------------------//
			ArrayList<MyRes> unmerge_results = new ArrayList<MyRes>();
			for (String field : fields) {
				QueryParser parser = new QueryParser(Version.LUCENE_40, field,
						this.ms.GetAnalyzer());
				// parsers.add(parser);

				Query query = null;
				try {
					query = parser.parse(rawquery);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				// search process
				// System.out.println("Field Searching for: " +
				// query.toString());
				TopDocs results = searcher.search(query, Path.ret_control);

				// append to umergedresults
				for (ScoreDoc sd : results.scoreDocs) {
					// ------show raw doc info
					/*
					 * String outputline = "Document id: " +
					 * searcher.doc(sd.doc).get("id") + "\n" + "Title: " +
					 * searcher.doc(sd.doc).get("title") + "\n" +
					 * "search Field: " + field + "\n" + "Score: " + sd.score +
					 * "\n\n"; System.out.println(outputline);
					 */
					// --record--//
					MyRes temp = new MyRes();
					temp.field = field;
					temp.id = Integer.parseInt(searcher.doc(sd.doc).get("id"));
					temp.title = searcher.doc(sd.doc).get("title");
					temp.Score = sd.score;
					unmerge_results.add(temp);
				}

			}
			// ------sort resluts by id--------------//
			Collections.sort(unmerge_results, new SortById());

			// ----------get return list-------//
			idlist = MyRes.GetIdList(MyRes.MergeResList(unmerge_results));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
		}
		return idlist;
	}

	/**
	 * @param args
	 * @throws IOException
	 */

	public float TestBed(float r_title, int ret_control) throws IOException {
		Path.Init(Path.source, r_title, ret_control);// init source and set
											// title_vs_content = title set ret
											// control
		SearchLucene sl = new SearchLucene(Path.current_index_path);// load the
																	// index
																	// file
		String[] fields = { "content", "title" };// make the field
		Lisa_Que_Rel lqr = new Lisa_Que_Rel();// load the rel and query

		float MAPsum = 0f;
		for (int i = 0; i < lqr.querynumber; i++) {
			MAPsum += CalcMap.GetMap(lqr.que_rels.get(i),
					sl.Search(fields, lqr.query.get(i)));

			if (Path.show) System.out
					.println("---------------------------------------------------------------------------");
		}
		return MAPsum / lqr.querynumber;
	}

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Path.Init(0);// init source and set vs=1
		SearchLucene sl = new SearchLucene(Path.current_index_path);// load the
																	// index
																	// file
		String[] fields = { "content", "title" };// make the field
		@SuppressWarnings("unused")
		Lisa_Que_Rel lqr = new Lisa_Que_Rel();// load the test bed

		sl.Search(
				fields,
				"I AM INTERESTED IN THE IDENTIFICATION AND EVALUATION OF NOVEL COMPUTER ARCHITECTURES, FOR INSTANCE, INCREASED PARALLELISM, BOTH IN SIMD AND MIMD MACHINES.  I AM ALSO INTERESTED IN INFORMATION ABOUT ASSOCIATIVE STORES OR MEMORIES AND ASSOCIATIVE PROCESSORS. COMPUTER ARCHITECTURES, ASSOCIATIVE PROCESSORS, ASSOCIATIVE STORES ASSOCIATIVE MEMORY");
	}
}
